package com.yixin.hospital.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yixin.hospital.common.ApiResult;
import com.yixin.hospital.common.Constant;
import com.yixin.hospital.entity.bo.GodownDrugDetail;
import com.yixin.hospital.entity.bo.PageInfo;
import com.yixin.hospital.entity.bo.PurchaseOrderDetail;
import com.yixin.hospital.entity.domain.*;
import com.yixin.hospital.entity.dto.req.purchaseorder.GoDownDrugReqDTO;
import com.yixin.hospital.entity.dto.req.purchaseorder.GoDownExchangeDrugReqDTO;
import com.yixin.hospital.entity.dto.req.purchaseorder.GoDownExchangeDrugStatusReqDTO;
import com.yixin.hospital.entity.vo.*;
import com.yixin.hospital.enums.DrugDepositoryOtpTypeEnum;
import com.yixin.hospital.enums.GoDownExchangeStatusEnum;
import com.yixin.hospital.enums.GoDownStatusEnum;
import com.yixin.hospital.mapper.extend.GodownExchangeDrugExtendMapper;
import com.yixin.hospital.mapper.extend.GoDownExtendMapper;
import com.yixin.hospital.service.*;
import com.yixin.hospital.utils.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.yixin.hospital.common.Constant.format;

@RestController
@RequestMapping("/input-godown-exchange")
@Api(value = "调库单管理", tags = "调库单管理")
public class InputGodownExchangeController {

    @Resource
    GodownDrugService godownDrugService;
    @Resource
    DrugDepositoryDrugService drugDepositoryDrugService;
    @Resource
    DrugDepositoryController drugDepositoryController;

    @Resource
    GodownExchangeDrugExtendMapper godownExchangeDrugExtendMapper;
    @Resource
    GodownExchangeDrugService godownExchangeDrugService;

    @GetMapping("/list2")
    @ApiOperation(value = "调库单列表")
    public ApiResult<?> list(HttpServletRequest request, @RequestParam int currentPage, @RequestParam int pageSize) {
        ApiResult<List<DrugDepositoryVo>> inputListApiResult = drugDepositoryController.availableList(request, DrugDepositoryOtpTypeEnum.INPUT.getCode());
        ApiResult<List<DrugDepositoryVo>> outputListApiResult = drugDepositoryController.availableList(request, DrugDepositoryOtpTypeEnum.OUTPUT.getCode());
        if (CollectionUtils.isEmpty(inputListApiResult.getData()) && CollectionUtils.isEmpty(outputListApiResult.getData())) return ApiResult.success(inputListApiResult);

        List<Long> inputDrugDepositoryIds = inputListApiResult.getData().stream().map(DrugDepositoryVo::getId).collect(Collectors.toList());
        List<Long> outputDrugDepositoryIds = outputListApiResult.getData().stream().map(DrugDepositoryVo::getId).collect(Collectors.toList());
        IPage<GoDownExchangeDrugVo> page = godownExchangeDrugExtendMapper.pageVo(Page.of(currentPage, pageSize), outputDrugDepositoryIds, inputDrugDepositoryIds);
        PageInfo<GoDownExchangeDrugVo> pageInfo = new PageInfo<>();
        BeanUtil.copyProperties(page, pageInfo);
        pageInfo.setRecords(BeanUtil.copyToList(page.getRecords(), GoDownExchangeDrugVo.class));
        return ApiResult.success(pageInfo);
    }

    @GetMapping("/listInfo")
    @ApiOperation(value = "入库单详情")
    public ApiResult<?> ListInfo(@RequestParam String code) {
        List<GoDownExchangeDrugVo> detailList = godownExchangeDrugExtendMapper.detail(code);
        return ApiResult.success(detailList);
    }

    @PostMapping("/godown-exchange-drug")
    @ApiOperation(value = "申请调库")
    @Transactional
    public ApiResult<?> goDownExchangeDrug(@Valid @RequestBody GoDownExchangeDrugReqDTO goDownDrugReqDTO, HttpServletRequest request) {
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        List<GodownExchangeDrug> godownDrugList = new ArrayList<>();
        String code = "TK" + LocalDateTime.now().format(DateTimeFormatter.ofPattern(format));
        for (GoDownExchangeDrugReqDTO.GoDownDrugBO goDownDrugBO : goDownDrugReqDTO.getGoDownDrugBOList()) {
            GodownExchangeDrug godownDrug = new GodownExchangeDrug();
            godownDrug.setCode(code);
            godownDrug.setOutputDepositoryId(goDownDrugReqDTO.getOutputDepositoryId());
            godownDrug.setInputDepositoryId(goDownDrugReqDTO.getInputDepositoryId());
            godownDrug.setOutputDrugDepositoryDrugId(goDownDrugBO.getOutputDrugDepositoryDrugId());
            godownDrug.setInputDrugDepositoryDrugId(goDownDrugBO.getInputDrugDepositoryDrugId());
            godownDrug.setInputSourceNum(goDownDrugBO.getInputSourceNum());
            godownDrug.setOutputSourceNum(goDownDrugBO.getOutputSourceNum());
            godownDrug.setPutNum(goDownDrugBO.getNum());
            godownDrug.setCreatedBy(userName);
            godownDrug.setUpdatedBy(userName);
            godownDrugList.add(godownDrug);
        }
        godownExchangeDrugService.saveBatch(godownDrugList);
        return ApiResult.success();
    }

    @PostMapping("/godown-exchange-drug-status")
    @ApiOperation(value = "调库")
    @Transactional
    public ApiResult<?> goDownExchangeDrugStatus(@Valid @RequestBody GoDownExchangeDrugStatusReqDTO goDownExchangeDrugStatusReqDTO, HttpServletRequest request) {
        String userName = JwtUtil.getName(request.getHeader(Constant.AUTHORIZATION));
        List<GodownExchangeDrug> godownExchangeDrugList = godownExchangeDrugService.list(new LambdaQueryWrapper<GodownExchangeDrug>().eq(GodownExchangeDrug::getCode, goDownExchangeDrugStatusReqDTO.getCode()));
        GodownExchangeDrug queryGodownExchangeDrug = godownExchangeDrugList.get(0);
        Map<Long, DrugDepositoryDrug> drugDepositoryDrugMap = new HashMap<>();
        if (queryGodownExchangeDrug.getStatus().equals(GoDownExchangeStatusEnum.PENDING.getCode())) {
            List<Long> outputIds = godownExchangeDrugList.stream().map(GodownExchangeDrug::getOutputDrugDepositoryDrugId).collect(Collectors.toList());
            drugDepositoryDrugMap = drugDepositoryDrugService.listByIds(outputIds).stream().collect(Collectors.toMap(DrugDepositoryDrug::getId, Function.identity()));
        } else if (queryGodownExchangeDrug.getStatus().equals(GoDownExchangeStatusEnum.OUTPUT_DOWN.getCode())) {
            List<Long> inputIds = godownExchangeDrugList.stream().filter(godownExchangeDrug -> Objects.nonNull(godownExchangeDrug.getInputDrugDepositoryDrugId())).map(GodownExchangeDrug::getInputDrugDepositoryDrugId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(inputIds)) {
                drugDepositoryDrugMap = drugDepositoryDrugService.listByIds(inputIds).stream().collect(Collectors.toMap(DrugDepositoryDrug::getId, Function.identity()));
            }
        } else {
            return ApiResult.success();
        }
        List<DrugDepositoryDrug> drugDepositoryDrugList = new ArrayList<>();
        for (GodownExchangeDrug godownExchangeDrug : godownExchangeDrugList) {
            // 减库存/加库存
            DrugDepositoryDrug drugDepositoryDrug;
            if (godownExchangeDrug.getStatus().equals(GoDownExchangeStatusEnum.PENDING.getCode())) {
                drugDepositoryDrug = drugDepositoryDrugMap.get(godownExchangeDrug.getOutputDrugDepositoryDrugId());
                drugDepositoryDrug.setNum(drugDepositoryDrug.getNum() - godownExchangeDrug.getPutNum());
            } else if (godownExchangeDrug.getStatus().equals(GoDownExchangeStatusEnum.OUTPUT_DOWN.getCode())) {
                drugDepositoryDrug = drugDepositoryDrugMap.get(godownExchangeDrug.getInputDrugDepositoryDrugId());
                // 调入库 没有该药品时
                if (Objects.isNull(drugDepositoryDrug)) {
                    drugDepositoryDrug = new DrugDepositoryDrug();
                    DrugDepositoryDrug outputDrugDepositoryDrug = drugDepositoryDrugService.getById(godownExchangeDrug.getOutputDrugDepositoryDrugId());
                    BeanUtils.copyProperties(outputDrugDepositoryDrug, drugDepositoryDrug);
                    drugDepositoryDrug.setId(null);
                    drugDepositoryDrug.setDrugDepositoryId(godownExchangeDrug.getInputDepositoryId());
                    drugDepositoryDrug.setNum(godownExchangeDrug.getPutNum());
                    drugDepositoryDrugService.save(drugDepositoryDrug);
                } else {
                    drugDepositoryDrug.setNum(drugDepositoryDrug.getNum() + godownExchangeDrug.getPutNum());
                }
            } else {
                continue;
            }
            // 改状态
            godownExchangeDrug.setStatus(godownExchangeDrug.getStatus().equals(GoDownExchangeStatusEnum.PENDING.getCode()) ? GoDownExchangeStatusEnum.OUTPUT_DOWN.getCode() : GoDownExchangeStatusEnum.INPUT_DOWN.getCode());
            godownExchangeDrug.setUpdatedBy(userName);
            godownExchangeDrug.setUpdatedTime(new Date());
            drugDepositoryDrug.setUpdatedBy(userName);
            drugDepositoryDrug.setUpdatedTime(new Date());
            drugDepositoryDrugList.add(drugDepositoryDrug);
        }
        godownExchangeDrugService.updateBatchById(godownExchangeDrugList);
        drugDepositoryDrugService.updateBatchById(drugDepositoryDrugList);
        return ApiResult.success();
    }

}
